package cn.fl.repay.controller;

import cmm.mid.core.framework.page.DataResultVO;
import cmm.mid.core.framework.page.KeyValueVO;
import cmm.mid.core.framework.page.ListPageVO;
import cmm.mid.core.framework.page.Pager;
import cmm.web.core.framework.controller.BaseController;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.DateUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.fl.capital.dto.McrBillYLDDTO;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.mcr.api.IMcrBillMApiService;
import cn.fl.mcr.condition.McrBillMQC;
import cn.fl.mcr.dto.McrBillMDTO;
import cn.fl.repay.condition.InsOfflineRepayDtlQueryCondition;
import cn.fl.repay.condition.InsOfflineRepayLogQueryCondition;
import cn.fl.repay.constant.RepayConstant;
import cn.fl.repay.dto.InsOfflineRepayDtlDTO;
import cn.fl.repay.dto.InsOfflineRepayLogDTO;
import cn.fl.repay.service.IInsOfflineRepayDtlService;
import cn.fl.repay.service.IInsOfflineRepayLogService;
import cn.fl.repay.service.OfflineRepayStrategy;
import cn.fl.repay.service.OfflineRepayStrategyFactory;
import cn.fl.repay.vo.InsOfflineRepayDtlVO;
import cn.fl.repay.vo.InsOfflineRepayLogVO;
import cn.fl.system.constant.SysLogConstant;
import cn.fl.system.service.ISysDictionaryService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.sf.json.JSONArray;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 线下还款申请记录表 控制层
 */
@Controller
@RequestMapping("/repay/insOfflineRepayLog")
public class InsOfflineRepayLogController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(cn.fl.repay.controller.InsOfflineRepayLogController.class);

    /**
     * InsOfflineRepayLog 服务层BEAN
     */
    @Autowired
    private IInsOfflineRepayLogService insOfflineRepayLogService;
    @Autowired
    private IInsOfflineRepayDtlService insOfflineRepayDtlService;
    @Autowired
    private IMcrBillMApiService mcrBillMApiService;
    @Autowired
    private ISysDictionaryService sysDictionaryService;
    @Autowired
    private OfflineRepayStrategyFactory offlineRepayStrategyFactory;
    /**
     * 到列表页面
     */
    @RequestMapping(value = "/toListPage.do", method = {RequestMethod.GET})
    public ModelAndView toListPage(HttpServletRequest request, HttpServletResponse response) {
        BaseLogUtils.info(logger, "toListPage", "加载InsOfflineRepayLog列表页面.", CurrentThreadContext.getCurrentUserName());
        ModelAndView mav = new ModelAndView("repay/insOfflineRepayLog/insOfflineRepayLogList");

        List<KeyValueVO> applyStsCdList = this.sysDictionaryService.getKvList(RepayConstant.APPLY_STS_CD, CurrentThreadContext.getFlServiceSysCd(), CurrentThreadContext.getCurrentOrgCd());
        mav.addObject("applyStsCdList", applyStsCdList);
        return mav;
    }

    /**
     * 到新增页面
     */
    @RequestMapping(value = "/toAddPage.do", method = {RequestMethod.GET, RequestMethod.POST})
    public ModelAndView toAddPage(HttpServletRequest request, HttpServletResponse response) {
        BaseLogUtils.info(logger, "toAddPage", "加载InsOfflineRepayLog Add页面.", CurrentThreadContext.getCurrentUserName());
        ModelAndView mav = new ModelAndView("repay/insOfflineRepayLog/insOfflineRepayLogModify");

        List<KeyValueVO> repayTypCdList = this.sysDictionaryService.getKvList(RepayConstant.REPAY_TYP_CD, CurrentThreadContext.getFlServiceSysCd(), CurrentThreadContext.getCurrentOrgCd());
        mav.addObject("repayTypCdList", repayTypCdList);

        //this.prepare(request,mav);
        return mav;
    }

    /**
     * 到修改页面
     */
    @RequestMapping(value = "/toModifyPage.do", method = {RequestMethod.GET, RequestMethod.POST})
    public ModelAndView toModifyPage(HttpServletRequest request, HttpServletResponse response) {
        BaseLogUtils.info(logger, "toModifyPage", "加载InsOfflineRepayLog Modify页面.", CurrentThreadContext.getCurrentUserName());
        ModelAndView mav = new ModelAndView("repay/insOfflineRepayLog/insOfflineRepayLogModify");
        //this.prepare(request,mav);

        String id = request.getParameter("id");
        InsOfflineRepayLogVO insOfflineRepayLogVO = this.insOfflineRepayLogService.selectById(Long.valueOf(id));
        mav.addObject("insOfflineRepayLogVO", insOfflineRepayLogVO);

        List<KeyValueVO> repayTypCdList = this.sysDictionaryService.getKvList(RepayConstant.REPAY_TYP_CD, CurrentThreadContext.getFlServiceSysCd(), CurrentThreadContext.getCurrentOrgCd());
        mav.addObject("repayTypCdList", repayTypCdList);
        return mav;
    }

    //加载数据字典数据、传值等 ？
    public void prepare(HttpServletRequest request, ModelAndView mav) {

    }

    /**
     * 初始化列表
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/initList.do", method = {RequestMethod.GET})
    @ResponseBody
    public Object initInsOfflineRepayLogList(HttpServletRequest request, HttpServletResponse response) {
        String currentPage = request.getParameter("page");
        String pageSize = request.getParameter("pagesize");
        Pager page = new Pager();
        if (StringUtils.isNotEmpty(currentPage)) {
            page.setCurrentPage(Integer.parseInt(currentPage));
        }

        if (StringUtils.isNotEmpty(pageSize)) {
            page.setEveryPage(Integer.parseInt(pageSize));
        }

        InsOfflineRepayLogQueryCondition qc = new InsOfflineRepayLogQueryCondition();
        //TODO 设置查询条件？
        String crCntNo = request.getParameter("crCntNo");
        if (StringUtils.isNotEmpty(crCntNo)) {
            qc.setCrCntNo(crCntNo);
        }
        String applyStsCd = request.getParameter("applyStsCd");
        if (StringUtils.isNotEmpty(applyStsCd)) {
            qc.setApplyStsCd(applyStsCd);
        }
        String stDt = request.getParameter("stDt");
        String endDt = request.getParameter("endDt");
        String stFinDt = request.getParameter("stFinDt");
        String endFinDt = request.getParameter("endFinDt");
        String loanChannel = request.getParameter("loanChannel");
        if (StringUtils.isNotEmpty(loanChannel)) {
            qc.setLoanChannel(loanChannel);
        }
        if (StringUtils.isNotEmpty(stDt)) {
        	qc.setStDt(DateUtils.formatStringToDate(stDt, "yyyy-MM-dd"));
        }
        if (StringUtils.isNotEmpty(endDt)) {
            qc.setEndDt(DateUtils.formatStringToDate(endDt, "yyyy-MM-dd"));
        }
        if (StringUtils.isNotEmpty(stFinDt)) {
        	qc.setStFinDt(DateUtils.formatStringToDate(stFinDt, "yyyy-MM-dd"));
        }
        if (StringUtils.isNotEmpty(endFinDt)) {
        	qc.setEndFinDt(DateUtils.formatStringToDate(endFinDt, "yyyy-MM-dd"));
        }
        page.setCondition(qc);

        BaseLogUtils.info(logger, "initInsOfflineRepayLogList", "初始化InsOfflineRepayLog列表页面数据.DATA:" + JSONObject.toJSONString(page), CurrentThreadContext.getCurrentUserName());
        Pager pager = this.insOfflineRepayLogService.searchListPage(page);
        List<InsOfflineRepayLogVO> list = (List<InsOfflineRepayLogVO>) pager.getResultList();
        if (!CollectionUtils.isEmpty(list)) {
            List<String> codeGrpCdList = Arrays.asList(RepayConstant.REPAY_TYP_CD, RepayConstant.APPLY_STS_CD);
            Map<String, List<KeyValueVO>> kvListMap = sysDictionaryService.getMultiKvList(CurrentThreadContext.getFlServiceSysCd(), CurrentThreadContext.getCurrentOrgCd(), codeGrpCdList);
            Map<String, String> repayTypMap = kvListMap.get(RepayConstant.REPAY_TYP_CD).stream().collect(Collectors.toMap(KeyValueVO::getKey, KeyValueVO::getValue));
            Map<String, String> applyStsMap = kvListMap.get(RepayConstant.APPLY_STS_CD).stream().collect(Collectors.toMap(KeyValueVO::getKey, KeyValueVO::getValue));

            for (InsOfflineRepayLogVO vo : list) {
                vo.setRepayTypCdNm(repayTypMap.getOrDefault(vo.getRepayTypCd(), ""));
                vo.setApplyStsCdNm(applyStsMap.getOrDefault(vo.getApplyStsCd(), ""));
                InsOfflineRepayDtlQueryCondition qcDtl = new InsOfflineRepayDtlQueryCondition();
    			qcDtl.setApplyLogId(vo.getId());
    			qcDtl.setIsDel(0);
        		List<InsOfflineRepayDtlVO> searchList = insOfflineRepayDtlService.searchList(qcDtl);
        		if(cn.cmm.base.framework.utils.CollectionUtils.isNotEmpty(searchList)){
        			vo.setCapAmt(searchList.stream().mapToLong(InsOfflineRepayDtlVO :: getCapAmt).sum());
        			long damAmt = 0;
        			for (InsOfflineRepayDtlVO insOfflineRepayDtlVO : searchList) {
						if(null != insOfflineRepayDtlVO.getDamAmt()){
							damAmt += insOfflineRepayDtlVO.getDamAmt();
						}
					}
        			vo.setDamAmt(damAmt);
        			vo.setGrtAmt(searchList.stream().mapToLong(InsOfflineRepayDtlVO :: getGrtAmt).sum());
        			vo.setIntrAmt(searchList.stream().mapToLong(InsOfflineRepayDtlVO :: getIntrAmt).sum());
        			vo.setOvdGrtAmt(searchList.stream().mapToLong(InsOfflineRepayDtlVO :: getOvdGrtAmt).sum());
        			vo.setPntAmt(searchList.stream().mapToLong(InsOfflineRepayDtlVO :: getPntAmt).sum());
        		}
            }
        }
        ListPageVO<InsOfflineRepayLogVO> listPage = new ListPageVO<InsOfflineRepayLogVO>(list, pager.getTotalCount());

        return listPage;
    }

    /**
     * 删除数据
     */
    @RequestMapping(value = "/removeByIds.do", method = {RequestMethod.POST})
    @ResponseBody
    public DataResultVO removeInsOfflineRepayLogByIds(HttpServletRequest request, HttpServletResponse response) throws BaseException {
        String ids = request.getParameter("ids");
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, SysLogConstant.LOG_CMM_DELETE_SUCC);
        if (StringUtils.isEmpty(ids)) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(SysLogConstant.LOG_CMM_DATA_PK_IS_EMPTY);
            BaseLogUtils.info(logger, "removeInsOfflineRepayLogByIds", "删除InsOfflineRepayLog数据,主键参数为空!", CurrentThreadContext.getCurrentUserName());
            return result;
        }

        List<Long> idsList = new ArrayList<Long>();
        JSONArray idsArray = JSONArray.fromObject(ids);
        for (Object object : idsArray) {
            idsList.add(Long.valueOf(object.toString()));
        }

        try {
//            Long id = idsList.get(0);
//            InsOfflineRepayLogQueryCondition condition = new InsOfflineRepayLogQueryCondition();
//            condition.setId(id);
//            List<InsOfflineRepayLogVO> list = insOfflineRepayLogService.searchList(condition);
//            if (CollectionUtils.isEmpty(list)) {
//                BaseLogUtils.info(logger, "removeInsOfflineRepayLogByIds", "查找InsOfflineRepayLog数据失败,ID:" + id, CurrentThreadContext.getCurrentUserName());
//            }
//            InsOfflineRepayLogVO repayLogVO = list.get(0);
//            if (!repayLogVO.getApplyStsCd().equals(RepayConstant.APPLY_STS_CD_0)) {
//                BaseLogUtils.info(logger, "removeInsOfflineRepayLogByIds", "InsOfflineRepayLog状态错误,ID:" + id, CurrentThreadContext.getCurrentUserName());
//            }
            boolean success = this.insOfflineRepayLogService.removeByIds(idsList);
            if (!success) {
                result.setSuccess(BaseConstant.IS_YESNO_NO);
                result.setInfo(SysLogConstant.LOG_CMM_DELETE_FAIL);
                BaseLogUtils.info(logger, "removeInsOfflineRepayLogByIds", "删除InsOfflineRepayLog数据失败,ID:" + idsList.toString(), CurrentThreadContext.getCurrentUserName());
            }
            BaseLogUtils.info(logger, "removeInsOfflineRepayLogByIds", "删除InsOfflineRepayLog数据成功,ID:" + idsList.toString(), CurrentThreadContext.getCurrentUserName());
        } catch (BaseException ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(SysLogConstant.LOG_CMM_SYS_ERROR);
            BaseLogUtils.info(logger, "removeInsOfflineRepayLogByIds", "删除InsOfflineRepayLog数据失败,ID:" + idsList.toString() + ".ERROR:" + ex.getMessage(), CurrentThreadContext.getCurrentUserName());
        } catch (Exception ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(SysLogConstant.LOG_CMM_SYS_ERROR);
            BaseLogUtils.error(logger, "removeInsOfflineRepayLogByIds", "删除InsOfflineRepayLog数据失败,系统错误.ID:" + idsList.toString() + ".ERROR:" + ex.getMessage(), CurrentThreadContext.getCurrentUserName());
        }
        return result;
    }

    /**
     * 得到一条记录
     *
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getById.do", method = {RequestMethod.GET})
    @ResponseBody
    public Object getInsOfflineRepayLogById(HttpServletRequest request, HttpServletResponse response) throws BaseException {
        String id = request.getParameter("id");
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, SysLogConstant.LOG_CMM_OPERATE_SUCC);
        if (StringUtils.isEmpty(id)) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(SysLogConstant.LOG_CMM_DATA_PK_IS_EMPTY);
            BaseLogUtils.info(logger, "getInsOfflineRepayLogById", "获取InsOfflineRepayLog数据,主键参数为空.", CurrentThreadContext.getCurrentUserName());
            return result;
        }

        try {
            InsOfflineRepayLogVO vo = this.insOfflineRepayLogService.selectById(Long.valueOf(id));
            if (null == vo) {
                result.setSuccess(BaseConstant.IS_YESNO_NO);
                result.setInfo(SysLogConstant.LOG_CMM_QUERY_DATA_IS_EMPTY);
                BaseLogUtils.info(logger, "getInsOfflineRepayLogById", "获取InsOfflineRepayLog数据不存在,ID:" + id, CurrentThreadContext.getCurrentUserName());
            }
            result.setData(vo);
            BaseLogUtils.info(logger, "getInsOfflineRepayLogById", "获取InsOfflineRepayLog数据成功,ID:" + id, CurrentThreadContext.getCurrentUserName());
        } catch (BaseException ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(SysLogConstant.LOG_CMM_SYS_ERROR);
            BaseLogUtils.info(logger, "getInsOfflineRepayLogById", "获取InsOfflineRepayLog数据失败,ID:" + id + ".ERROR:" + ex.getMessage(), CurrentThreadContext.getCurrentUserName());
        } catch (Exception ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(SysLogConstant.LOG_CMM_SYS_ERROR);
            BaseLogUtils.error(logger, "getInsOfflineRepayLogById", "获取InsOfflineRepayLog数据失败,系统错误.ID:" + id + ".ERROR:" + ex.getMessage(), CurrentThreadContext.getCurrentUserName());
        }
        return result;
    }

    /**
     * 新增
     */
    @RequestMapping(value = "/add.do", method = {RequestMethod.POST})
    @ResponseBody
    public Object addInsOfflineRepayLog(HttpServletRequest request, HttpServletResponse response) throws BaseException {
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, SysLogConstant.LOG_CMM_ADD_SUCC);
        InsOfflineRepayLogVO repayLogVO = null;
        List<InsOfflineRepayDtlVO> repayDtlList = null;
        try {
            repayLogVO = this.getRequestParamForInsOfflineRepayLog(request);//获取参数
            repayDtlList = this.getRequestParamForInsOfflineRepayDtl(request);//获取参数

            McrBillMQC billMQC = new McrBillMQC();
            billMQC.setCrCntNo(repayLogVO.getCrCntNo());
            List<McrBillMDTO> billMDTOList = mcrBillMApiService.searchMcrBillMDTOList(billMQC);
            if (CollectionUtils.isEmpty(billMDTOList)) {
                throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "小贷账单不存在.");
            }
            McrBillMDTO billMDTO = billMDTOList.get(0);
            OfflineRepayStrategy offlineRepayStrategy = offlineRepayStrategyFactory.getRepayDtlStrategy(billMDTO.getLoanChannel());
            if (offlineRepayStrategy == null) {
                throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "不支持该资管机构，请联系产品经理.");
            }

            if (!offlineRepayStrategy.support(repayLogVO.getRepayTypCd())) {
                throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "此资管机构不能执行还款类型对应的业务操作.");
            }
            offlineRepayStrategy.checkRepayData(repayLogVO, repayDtlList);
            // 设置贷款渠道
            repayLogVO.setLoanChannel("");
            if (!org.apache.commons.lang3.StringUtils.isEmpty(billMDTO.getLoanChannel())) {
                repayLogVO.setLoanChannel(billMDTO.getLoanChannel());
            }
            // 亿联校验
            // 如果不同的资管有不同的校验规则，则需要进行代码重构
            if (repayLogVO.getLoanChannel().equals(RepayConstant.LOAN_CHANNEL_YLYH)) {
                InsOfflineRepayDtlVO repayDtlVO = repayDtlList.get(0);
                if (repayLogVO.getRepayTypCd().equals(RepayConstant.REPAY_TYP_CD_PD)) {
                    if (repayDtlVO.getPayPd() == null) {
                        throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "按期还款时不能使用结清数据.");
                    }
                } else {
                    if (repayDtlVO.getPayPd() != null) {
                        throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "结清还款时不能使用分期数据.");
                    }
                }
            }
            this.processInsOfflineRepayDtl(repayDtlList, repayLogVO);
            Long id = this.insOfflineRepayLogService.add(repayLogVO, repayDtlList);
            result.setData(id);
            BaseLogUtils.info(logger, "addInsOfflineRepayLog", "新增InsOfflineRepayLog数据成功,repayLogVO:" + JSON.toJSONString(repayLogVO) + ".repayDtlList:" + JSONObject.toJSONString(repayDtlList), CurrentThreadContext.getCurrentUserName());
        } catch (BaseException ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(SysLogConstant.LOG_CMM_SYS_ERROR + ex.getMessage());
            BaseLogUtils.info(logger, "addInsOfflineRepayLog", "新增InsOfflineRepayLog数据失败.repayLogVO:" + JSONObject.toJSONString(repayLogVO) + ".repayDtlList:" + JSONObject.toJSONString(repayDtlList) + ".ERROR:" + ex.getMessage(), CurrentThreadContext.getCurrentUserName());
        } catch (Exception ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(SysLogConstant.LOG_CMM_SYS_ERROR + ex.getMessage());
            BaseLogUtils.error(logger, "addInsOfflineRepayLog", "新增InsOfflineRepayLog数据失败,系统错误.DATA:" + JSONObject.toJSONString(repayLogVO) + ".ERROR:" + ex.getMessage(), CurrentThreadContext.getCurrentUserName());
        }
        return result;
    }

    /**
     * 修改
     */
    @RequestMapping(value = "/modify.do", method = {RequestMethod.POST})
    @ResponseBody
    public Object modifyInsOfflineRepayLog(HttpServletRequest request, HttpServletResponse response) throws BaseException {
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, SysLogConstant.LOG_CMM_UPDATE_SUCC);
        InsOfflineRepayLogVO entity = null;
        try {
            entity = this.getRequestParamForInsOfflineRepayLog(request);
            if (entity.getId() == null) {
                result.setSuccess(BaseConstant.IS_YESNO_NO);
                result.setInfo(SysLogConstant.LOG_CMM_DATA_PK_IS_EMPTY);
                BaseLogUtils.info(logger, "modifyInsOfflineRepayLog", "修改InsOfflineRepayLog信息,主键参数为空！.", CurrentThreadContext.getCurrentUserName());
                return result;
            }

            boolean success = this.insOfflineRepayLogService.modify(entity);
            if (!success) {
                result.setSuccess(BaseConstant.IS_YESNO_NO);
                result.setInfo(SysLogConstant.LOG_CMM_UPDATE_FAIL);
                BaseLogUtils.info(logger, "modifyInsOfflineRepayLog", "修改InsOfflineRepayLog数据失败.DATA:" + JSONObject.toJSONString(entity), CurrentThreadContext.getCurrentUserName());
                return result;
            }
            BaseLogUtils.info(logger, "modifyInsOfflineRepayLog", "修改InsOfflineRepayLog数据成功.DATA:" + JSONObject.toJSONString(entity), CurrentThreadContext.getCurrentUserName());
        } catch (BaseException ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(SysLogConstant.LOG_CMM_SYS_ERROR + ex.getMessage());
            BaseLogUtils.info(logger, "modifyInsOfflineRepayLog", "修改InsOfflineRepayLog数据失败.DATA:" + JSONObject.toJSONString(entity) + ".ERROR:" + ex.getMessage(), CurrentThreadContext.getCurrentUserName());
        } catch (Exception ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(SysLogConstant.LOG_CMM_SYS_ERROR + ex.getMessage());
            BaseLogUtils.error(logger, "modifyInsOfflineRepayLog", "修改InsOfflineRepayLog数据失败,系统错误.DATA:" + JSONObject.toJSONString(entity) + ".ERROR:" + ex.getMessage(), CurrentThreadContext.getCurrentUserName());
        }
        return result;
    }

    /**
     * 获取请求参数
     *
     * @param request 请求
     * @return
     */
    private InsOfflineRepayLogVO getRequestParamForInsOfflineRepayLog(HttpServletRequest request) throws BaseException {
        //获取参数
        String id = request.getParameter("id");//主键
//        String billId = request.getParameter("billId");//账单ID
        String crCntNo = request.getParameter("crCntNo");//账单编号（贷款合同号）
        String actPayDt = request.getParameter("actPayDt");//线下实还时间
        String repayTypCd = request.getParameter("repayTypCd");//还款类型：1.按期还款 2.结清还款
        String repayAmt = request.getParameter("repayAmt");//还款金额（分）

        if (StringUtils.isBlank(crCntNo)) {
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "合同号不能为空.");
        }
        if (StringUtils.isBlank(actPayDt)) {
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "实际还款时间不能为空.");
        }
        if (StringUtils.isBlank(repayTypCd)) {
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "还款类型不能为空.");
        }
        if (StringUtils.isNotBlank(repayAmt)) {
            if (!StringUtils.isUnsignedNumeric(repayAmt)) {
                throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "还款金额错误.");
            }
        } else {
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "还款金额不能为空.");
        }

        //验证参数并赋值
        InsOfflineRepayLogVO entity = new InsOfflineRepayLogVO();
//        entity.setBillId(Long.parseLong(billId));//账单ID
        entity.setCrCntNo(crCntNo);//账单编号（贷款合同号）
        entity.setActPayDt(DateUtils.formatStringToDate(actPayDt, "yyyy-MM-dd"));//线下实还时间
        entity.setRepayTypCd(repayTypCd);//还款类型：1.按期还款 2.结清还款
        if (NumberUtils.isNumber(repayAmt)) {
            BigDecimal yuan = new BigDecimal(repayAmt);
            long fen = yuan.multiply(BigDecimal.valueOf(100)).longValue();
            entity.setRepayAmt(fen);//还款金额（分）
        }
//        entity.setApplyStsCd("0");//申请还款状态0.处理中 1.还款成功 2.还款失败

        McrBillMQC billMQC = new McrBillMQC();
        billMQC.setCrCntNo(crCntNo);
        List<McrBillMDTO> billMDTOList = mcrBillMApiService.searchMcrBillMDTOList(billMQC);
        if (CollectionUtils.isEmpty(billMDTOList)) {
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "小贷账单不存在.");
        }
        McrBillMDTO billMDTO = billMDTOList.get(0);
        entity.setBillId(billMDTO.getId());

        Date tm = new Date();
        if (StringUtils.isNotBlank(id)) {
            entity.setId(Long.valueOf(id));
            entity.setMdfTm(tm);
            entity.setMdfUsrId(CurrentThreadContext.getCurrentUserId());
        } else {
            entity.setCrtTm(tm);
            entity.setCrtUsrId(CurrentThreadContext.getCurrentUserId());
        }

        return entity;
    }

    private List<InsOfflineRepayDtlVO> getRequestParamForInsOfflineRepayDtl(HttpServletRequest request) {
        String repayPlans = request.getParameter("repayPlans");// 还款计划
        if (StringUtils.isBlank(repayPlans)) {
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "还款计划不能为空.");
        }
        // 还款明细
        List<InsOfflineRepayDtlVO> repayDtlVOList = JSONObject.parseArray(repayPlans, InsOfflineRepayDtlVO.class);
        if (CollectionUtils.isEmpty(repayDtlVOList)) {
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "还款计划不能为空.");
        }
        return repayDtlVOList;
    }

    private void processInsOfflineRepayDtl(List<InsOfflineRepayDtlVO> repayDtlList, InsOfflineRepayLogVO repayLogVO) {
        for (InsOfflineRepayDtlVO vo : repayDtlList) {
            // 此步骤移到服务层实现
//            vo.setApplyLogId(repayLogVO.getId());
            vo.setCrtTm(repayLogVO.getCrtTm());
            vo.setCrtUsrId(CurrentThreadContext.getCurrentUserId());
        }
    }

    /**
     * 还款试算
     */
    @RequestMapping(value = "/queryReplayPlan.do", method = {RequestMethod.GET})
    @ResponseBody
    public Object queryReplayPlan(HttpServletRequest request, HttpServletResponse response) throws BaseException {
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, SysLogConstant.LOG_CMM_DELETE_SUCC);
        // 合同号
        String crCntNo = request.getParameter("crCntNo");
        // TODO 日期需格式化为 YYYY/MM/DD
        String actPayDt = request.getParameter("actPayDt");
        // 还款类型
        String repayTypCd = request.getParameter("repayTypCd");

        Map<String, List<InsOfflineRepayDtlVO>> retMap = null;
        try {
            if (StringUtils.isEmpty(crCntNo) || StringUtils.isEmpty(actPayDt) || StringUtils.isEmpty(repayTypCd)) {
                throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "请填写合同号、还款类型和线下还款时间.");
            }

            McrBillMQC billMQC = new McrBillMQC();
            billMQC.setCrCntNo(crCntNo);
            BaseLogUtils.info(logger, "queryReplayPlan", "mcrBillMApiService.searchMcrBillMDTOList.REQUEST:" + JSONObject.toJSONString(billMQC), CurrentThreadContext.getCurrentUserName());
            List<McrBillMDTO> billMDTOList = mcrBillMApiService.searchMcrBillMDTOList(billMQC);
            BaseLogUtils.info(logger, "queryReplayPlan", "mcrBillMApiService.searchMcrBillMDTOList.RESPONSE:" + JSONObject.toJSONString(billMDTOList), CurrentThreadContext.getCurrentUserName());
            if (CollectionUtils.isEmpty(billMDTOList)) {
                throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "小贷账单不存在.");
            }
            McrBillMDTO billMDTO = billMDTOList.get(0);
            OfflineRepayStrategy offlineRepayStrategy = offlineRepayStrategyFactory.getRepayDtlStrategy(billMDTO.getLoanChannel());
            if (offlineRepayStrategy == null) {
                throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_604, "资管机构不支持.");
            }
            List<InsOfflineRepayDtlVO> repayDtlVOList = offlineRepayStrategy.getRepayDtl(crCntNo, repayTypCd, actPayDt);

            retMap = new HashMap<>();
            retMap.put("rows", repayDtlVOList);
        } catch (Exception ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(ex.getMessage());
            BaseLogUtils.error(logger, "queryReplayPlan", "获取InsOfflineRepayDtl数据失败.crCntNo:" + crCntNo + ".ERROR:" + ex.getMessage(), CurrentThreadContext.getCurrentUserName());
        }
        return retMap;
    }
    /**
     * 还款试算
     */
    @RequestMapping(value = "/sumRepayData.do", method = {RequestMethod.GET})
    @ResponseBody
    public Map<String, String> sumRepayData(HttpServletRequest request, HttpServletResponse response) throws BaseException {

        InsOfflineRepayLogQueryCondition qc = new InsOfflineRepayLogQueryCondition();
        //TODO 设置查询条件？
        String crCntNo = request.getParameter("crCntNo");
        if (StringUtils.isNotEmpty(crCntNo)) {
            qc.setCrCntNo(crCntNo);
        }
        String applyStsCd = request.getParameter("applyStsCd");
        if (StringUtils.isNotEmpty(applyStsCd)) {
            qc.setApplyStsCd(applyStsCd);
        }
        String stDt = request.getParameter("stDt");
        String endDt = request.getParameter("endDt");
        String stFinDt = request.getParameter("stFinDt");
        String endFinDt = request.getParameter("endFinDt");
        String loanChannel = request.getParameter("loanChannel");
        if (StringUtils.isNotEmpty(loanChannel)) {
            qc.setLoanChannel(loanChannel);
        }
        if (StringUtils.isNotEmpty(stDt)) {
            qc.setStDt(DateUtils.formatStringToDate(stDt, "yyyy-MM-dd"));
        }
        if (StringUtils.isNotEmpty(endDt)) {
            qc.setEndDt(DateUtils.formatStringToDate(endDt, "yyyy-MM-dd"));
        }
        if (StringUtils.isNotEmpty(stFinDt)) {
        	qc.setStFinDt(DateUtils.formatStringToDate(stFinDt, "yyyy-MM-dd"));
        }
        if (StringUtils.isNotEmpty(endFinDt)) {
        	qc.setEndFinDt(DateUtils.formatStringToDate(endFinDt, "yyyy-MM-dd"));
        }

        Map<String, String> hashMap = this.insOfflineRepayLogService.searchSumAmt(qc);
        if(null == hashMap){
        	hashMap = new HashMap<>();
        }
        if(null == hashMap.get("SUMAMT")){
        	hashMap.put("SUMAMT", "0");
        }
        if(null == hashMap.get("SUMCIPAMT")){
        	hashMap.put("SUMCIPAMT", "0");
        }
        return hashMap;
    }
}

